import S from 'ant-design-vue/es/select'
import dic from '@/utils/dic'
import { axios } from '@/utils/request'

export default {
  model: {
    prop: 'value',
    event: 'change'
  },
  data () {
    return {
      // local + 原始属性，可通过控制 localxxx 来修改 原始属性，以解决 props 属性在子类中修改报错的问题
      localOptions: [],
      localValue: this.value || this.defaultValue || undefined,
      optionData: []
    }
  },
  // 扩展属性，或覆盖原属性
  props: Object.assign({}, S.props, {
    placeholder: {
      type: String,
      default: '请选择'
    },
    allowClear: {
      type: Boolean,
      default: true
    },
    showSearch: {
      type: Boolean,
      default: true
    },
    /**
     * 远程配置 - 使用远程请求数据
     */
    remote: {
      type: Object,
      default: function () {
        return {
          url: '',
          method: 'get',
          params: {},
          formatter: function () {},
          properties: {
            label: '',
            value: ''
          }
        }
      }
    },
    /**
     * 字典类型 - 使用缓存
     */
    dType: {
      type: String
    },
    /**
     * 元素
     * [{label: '显示名称', value: 'number/string', disabled: false}]
     */
    data: {
      type: Array,
      default: function () {
        return []
      }
    },
    /**
     * 分页参数，避免下拉项过多导致的卡顿问题（适用于查询场景）小于1 则表示不启用分页
     */
    pageNum: {
      type: Number,
      default: 15
    }
  }),
  watch: {
    value (val, oldVal) {
      this.localValue = val || this.defaultValue
    },
    data (val, oldVal) {
      // this.optionData = val
      this.loadLocalData()
    },
    remote () {
      this.loadLocalData()
    },
    dType () {
      this.loadLocalData()
    }
  },
  created () {
    this.loadLocalData()
  },
  methods: {
    loadLocalData () {
      if (this.data && this.data.length > 0) {
        // 执行本地数据格式转换
        this.translateData(this.data)
      } else if (this.remote && this.remote.url) {
        const remote = Object.assign({
          header: { 'Content-Type': 'application/json;charset=UTF-8' },
          method: 'get',
          params: {},
          formatter: function () {},
          properties: {
            label: '',
            value: ''
          }
        }, this.remote)
        // 执行远程请求 这里耦合进来 封装方法
        axios(remote, this.remote).then(res => {
          // properties 转换层 做转换处理，formatter 做自定义扩展处理
          this.translateData(res.data || [])
        })
      } else if (this.dType) {
        this.translateData(dic.query(this.dType) || [])
      }
    },
    translateData (data) {
      const options = []
      data.forEach(item => {
        // 考虑处理拼音等
        options.push({
          title: `${item.label}`,
          value: item.value,
          key: item.value + '',
          disabled: item.disabled || false
        })
      })
      this.optionData = options
      this.filterLocalOptions()
    },
    handleChange (value, node) {
      this.localValue = value
      this.$emit('change', value, node)
    },
    handleSearch (input) {
      this.filterLocalOptions(input || '')
    },
    handleFilterOption (input, option) {
      return (
        option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
      )
    },
    // 这里缓存、切割和过滤处理
    filterLocalOptions (input) {
      if (input) {
        input = (input + '').toLowerCase()
      }
      if (!input && this.pageNum < 1) {
        this.localOptions = this.optionData
      } else {
        if (this.localOptions.length > 0) {
          this.localOptions.slice(0, this.localOptions.length)
        }
        const that = this
        const options = []
        this.optionData.some(item => {
          if (that.pageNum > 0 && options.length >= this.pageNum) {
            return true
          } else {
            if (input) {
              if (item.title.indexOf(input) > -1) {
                options.push(item)
              }
            } else {
              options.push(item)
            }
          }
        })
        this.localOptions = options
      }
    }
  },
  render () {
    const props = {}
    const localKeys = Object.keys(this.$data)
    Object.keys(S.props).forEach(k => {
      const localKey = `local${k.substring(0, 1).toUpperCase()}${k.substring(1)}`
      if (localKeys.includes(localKey)) {
        props[k] = this[localKey]
        return props[k]
      }
      this[k] && (props[k] = this[k])
      return props[k]
    })

    const select = (
      <a-select {...{ props, scopedSlots: { ...this.$scopedSlots } }} filter-option={this.handleFilterOption} onChange={this.handleChange} onSearch={this.handleSearch}>
        { Object.keys(this.$slots).map(name => (<template slot={name}>{this.$slots[name]}</template>)) }
      </a-select>
    )

    return (
      <div>
        {select}
      </div>
    )
  }
}
